// make.c

#include <ansi.h>
#include <medical.h>

inherit F_CLEAN_UP;

void create() { seteuid(getuid()); }

int main(object me, string arg)
{
    object qm;
    object hob;
    string med;
    mapping make;
    mapping req;
    mapping herb;
    string *ks;
    object *hlist;
    string msg;
    int only_list;
    int i;

    if (!arg)
    {
        make = me->query("can_make");
        if (!mapp(make))
            return notify_fail("你现在不会制任何药物。\n");

        ks = keys(make);
        msg = "你现在已经会制";
        if (sizeof(ks) >= 2)
            msg += implode(ks[0..sizeof(ks)-2], "、") +
                   "和" + ks[sizeof(ks) - 1] + "了。\n";
        else
            msg += ks[0] + "了。\n";
        msg = sort_string(msg, 64);
        write(msg);
        return 1;
    }

    // only for list?
    only_list = sscanf(arg, "%s ?", arg);

    if (!stringp(med = me->query("can_make/" + arg)))
        return notify_fail("你还不会配这种药啊！\n");

    // The player can only make the medicine under the /clone/medicine,
    // nothing, but for save memory.
    med = MEDICINE(med);
    if (file_size(med + ".c") < 0)
        return notify_fail("这种药方好像已经失传了？你还是问问巫师吧。\n");

    if (!mapp(req = med->query("mixture")))
        return notify_fail(med->name() + "好像无法配制...\n");

    if (!mapp(herb = req["herb"]))
        return notify_fail(med->name() + "需要什么原料呢...\n");

    if (only_list)
    {
        // show herb
        write("炼制" + arg + "需要以下这些药材：\n");
        ks = keys(herb);
        for (i = 0; i < sizeof(ks); i++)
        {
            write(chinese_number(herb[ks[i]]) + HERB(ks[i])->query("base_unit") +
                  HERB(ks[i])->name() + "\n");
        }
        return 1;
    }

    if (me->is_fighting())
        return notify_fail("打架的时候你还有闲工夫配药？\n");

    if (me->is_busy())
        return notify_fail("还是先把手头的事情忙完吧。\n");

    if (environment(me)->query("no_fight") && 0)
        return notify_fail("你在这里制药只怕要打扰到别人。\n");

    qm = me->query_temp("handing");
    if (!qm)
        return notify_fail("你的先把能够磨药的研钵拿(hand)在手上才行。\n");

    if (!qm->can_make_medicine())
        return notify_fail(qm->name() + "好像无法发挥研钵的作用吧。\n");

    if (sizeof(all_inventory(qm)) > 0)
        return notify_fail("你还是先把" + qm->name() + "里面的东西拿出来再说。\n");

    if (me->query("jing") < me->query("max_jing") * 7 / 10)
        return notify_fail("你现在精神难以集中，无法配药。\n");

    ks = keys(req) - ({"herb", "neili", "jing", "jingli", "min_level", "time"});

    // check skills
    for (i = 0; i < sizeof(ks); i++)
        if (me->query_skill(ks[i], 1) < req[ks[i]])
            return notify_fail("你的" + to_chinese(ks[i]) +
                               "水平不够，还无法调剂" +
                               med->name() + "。\n");

    // check herb
    ks = keys(herb);
    hlist = allocate(sizeof(ks));
    for (i = 0; i < sizeof(ks); i++)
    {
        hob = present("herb_" + ks[i], me);
        if (!hob || hob->query_amount() < herb[ks[i]])
        {
            if (file_size(HERB(ks[i]) + ".c") < 0)
            {
                write("没有(" + ks[i] + ")这种药材啊！怎么回事？\n");
                return 1;
            }
            return notify_fail("你点了点药材，发现" +
                               HERB(ks[i])->name() +
                               "的分量还不够。\n");
        }
        hlist[i] = hob;
    }

    // decrease herb
    msg = "你选出";
    for (i = 0; i < sizeof(ks); i++)
    {
        if (i)
            msg += "、";
        msg += chinese_number(herb[ks[i]]) +
               hlist[i]->query("base_unit") +
               hlist[i]->name();
        hlist[i]->add_amount(-herb[ks[i]]);
    }
    msg += "，然后小心翼翼的把它们放到" + qm->name() + "里面，开始制药。\n";
    msg = sort_string(msg, 64);
    write(msg);
    message("vision", me->name() + "东摸摸，西弄弄，不知道在干啥。\n",
            environment(me), ({me}));
    me->start_busy(bind((: call_other, __FILE__, "making" :), me),
                   bind((: call_other, __FILE__, "halt_make" :), me));
    me->set_short_desc("正在专心致志的炼制药物。");
    me->set_temp("pending/making", 0);
    me->set_temp("making/medicine", med);
    me->set_temp("making/time", (int)req["time"]);
    me->set_temp("making/require", req);
    me->set_temp("making/container", qm);
    return 1;
}

int stop_making(object me)
{
    me->delete_temp("making");
    me->delete_temp("pending/making");
    me->set_short_desc(0);
    return 0;
}

int making(object me)
{
    int step;
    mapping req;
    string msg_me, msg_out;
    string med;
    object ob;
    object qm;

    step = me->query_temp("pending/making");
    req = me->query_temp("making/require");
    med = me->query_temp("making/medicine");
    qm = me->query_temp("making/container");
    if (qm != me->query_temp("handing"))
    {
        write("嗯？研钵呢...？我的研钵！\n");
        return stop_making(me);
    }

    switch (step)
    {
    default:
        step = 0;
        msg_me = "你拿起棒杵，慢慢的捣着" + qm->name() + "里面的药材。\n";
        msg_out = "$N拿起棒杵叮咣叮咣的捣得很起劲。\n";
        break;
    case 1:
        msg_me = "扑哧扑哧，药材眼见变成了一块块小碎块。\n";
        msg_out = "$N没完没了的捣鼓。\n";
        break;
    case 2:
        msg_me = "你轻轻的研磨着药材，让它越来越细。\n";
        msg_out = "$N紧张的磨着东西。\n";
        break;
    case 3:
        msg_me = "你接着把那些残留的大块儿一点的药材捣碎。\n";
        msg_out = "$N突然又叮咣叮咣的捣个不停。\n";
        break;
    case 4:
        msg_me = "你细细的将所有的药材磨成了粉末。\n";
        msg_out = "$N拿着棒杵磨来磨去。\n";
        break;
    case 5:
        msg_me = "你轻轻的合上" + qm->name() +
                 "，默默的运用内力，烘培里面的药材。\n";
        msg_out = "$N合上" + qm->name() + "，双手抱着，不知道在干什么。\n";
        break;
    case 6:
        if (me->query("jing") < req["jing"])
        {
            write("你觉得精神不济，看来难以继续调剂「" +
                  med->name() + "」。\n");
            return stop_making(me);
        }

        if (me->query("neili") < req["neili"])
        {
            write("你觉得内力不济，看来难以继续调剂「" +
                  med->name() + "」。\n");
            return stop_making(me);
        }

        if (me->query("jingli") < req["jingli"])
        {
            write("你觉得精力不济，看来难以继续调剂「" +
                  med->name() + "」。\n");
            return stop_making(me);
        }

        me->receive_damage("jing", req["jing"]);
        me->add("neili", -req["neili"]);
        me->add("jingli", -req["jingli"]);

        if (me->add_temp("making/time", -1) > 0)
        {
            // when time > 0, next busy stage will
            // still at 6, becuase the step will be
            // increase by 1 later, so I decrase it
            // first
            step--;
        }

        msg_me = random(2) ? "你觉得" + qm->name() + "慢慢的热了起来，感"
                             "觉到里面的药材似乎已经融化了。\n"
                           : "你不断的将内力传入" + qm->name() + "，发热"
                             "使里面的药材融化合一。\n";
        msg_out = random(2) ? "$N像老和尚一样闭目冥神坐在那里。\n"
                            : "$N手里握着" + qm->name() + "没完没了的转来转去。\n";

        break;
    case 7:
        msg_me = "你运用内力，隔着" + qm->name() + "使里面的药材彻底的融合。\n";
        msg_out = "$N眉毛动了动，接着又像老和尚一样闭目冥神坐在那里。\n";
        break;
    case 8:
        msg_me = "你长吁了一口气，慢慢的把手拿开，打开了" + qm->name() + "。\n";
        msg_out = "$N长吁了一口气，慢慢的把手拿开，打开了" + qm->name() + "。\n";
        break;
    case 9:
        if (random(me->query_skill("medical", 1) +
                   qm->query("item_prop/medical")) >= req["min_level"])
        {
            ob = new (med);
            ob->move(qm, 1);
            msg_me = HIM "你把「" + ob->name() + HIM "」成功的制好了！\n" NOR;
            msg_out = HIM "$N" HIM "嘴角露出一丝微笑。\n" NOR;
        }
        else if (!me->query("special_skill/lucky") || random(2) == 0)
        {
            msg_me = HIG "真令人沮丧！居然失败了，真是可惜了。\n" NOR;
            msg_out = HIG "$N" HIG "一脸沮丧，不"
                          "知道发生了什么倒霉事。\n" NOR;
        }
        else
        {
            ob = new (med);
            ob->move(qm, 1);
            msg_me = HIM "你感觉似乎有什么地方没有做对，然而你的运气实在太好了！\n你把「" + ob->name() + HIM "」成功的制好了！\n" NOR;
            msg_out = HIM "$N" HIM "嘴角露出一丝微笑。\n" NOR;
        }
        break;
    }

    msg_out = replace_string(msg_out, "$N", me->name());
    message("vision", msg_me, me);
    message("vision", msg_out, environment(me), ({me}));
    step++;
    if (step >= 10)
        // end of making
        return stop_making(me);

    me->set_temp("pending/making", step);
    return 1;
}

int halt_make(object me)
{
    message_vision("$N把手中的研钵一翻个，东西"
                   "全都倒了出来。\n",
                   me);
    stop_making(me);
    return 1;
}

int help(object me)
{
    write(@HELP
指令格式 : make [<药品>] [?]

这个指令可以让你炼制某样药品，如果没有指明药品则会列出当前
你会炼制的药品。如果在指明的药品后面添加一个"?" 则会列出炼
制这种药品需要的材料。

HELP );
    return 1;
}
